#ifndef HEADER_SDF_H
#define HEADER_SDF_H

#include <stdio.h>
#include "sgd.h"

#ifdef __cplusplus
extern "C" {
#endif

#pragma pack(1)

typedef struct DeviceInfo_st {
    unsigned char IssuerName[40];
    unsigned char DeviceName[16];
    unsigned char DeviceSerial[16];
    unsigned int DeviceVersion;
    unsigned int StandardVersion;
    unsigned int AsymAlgAbility[2];
    unsigned int SymAlgAbility;
    unsigned int HashAlgAbility;
    unsigned int BufferSize;
} DEVICEINFO;

typedef struct RSArefPublicKey_st {
    unsigned int bits;
    unsigned char m[256]; // 假设最大长度为256
    unsigned char e[256];
} RSArefPublicKey;

typedef struct RSArefPrivateKey_st {
    unsigned int bits;
    unsigned char m[256];
    unsigned char e[256];
    unsigned char d[256];
    unsigned char prime[2][128];
    unsigned char pexp[2][128];
    unsigned char coef[128];
} RSArefPrivateKey;

typedef struct ECCrefPublicKey_st {
    unsigned int bits;
    unsigned char x[64];
    unsigned char y[64];
} ECCrefPublicKey;

typedef struct ECCrefPrivateKey_st {
    unsigned int bits;
    unsigned char K[64];
} ECCrefPrivateKey;

typedef struct ECCCipher_st {
    unsigned char x[64];
    unsigned char y[64];
    unsigned char M[32];
    unsigned int L;
    unsigned char C[1];
    unsigned char C_[254]; // 扩展C的sizeof以适应SM2_MAX_PLAINTEXT_SIZE
} ECCCipher;

typedef struct ECCSignature_st {
    unsigned char r[64];
    unsigned char s[64];
} ECCSignature;

typedef struct SDF_ENVELOPEDKEYBLOB {
    unsigned long Version;
    unsigned long ulSymmAlgID;
    ECCCipher ECCCipherBlob;
    ECCrefPublicKey PubKey;
    unsigned char cbEncryptedPrivKey[64];
} EnvelopedKeyBlob, *PEnvelopedKeyBlob;

#pragma pack()

// 错误码定义
#define SDR_OK                 0x0
#define SDR_BASE              0x01000000
#define SDR_UNKNOWERR          (SDR_BASE + 0x00000001)
#define SDR_NOTSUPPORT         (SDR_BASE + 0x00000002)
#define SDR_COMMFAIL           (SDR_BASE + 0x00000003)
#define SDR_HARDFAIL           (SDR_BASE + 0x00000004)
#define SDR_OPENDEVICE         (SDR_BASE + 0x00000005)
#define SDR_OPENSESSION        (SDR_BASE + 0x00000006)
#define SDR_PARDENY            (SDR_BASE + 0x00000007)
#define SDR_KEYNOTEXIST        (SDR_BASE + 0x00000008)
#define SDR_ALGNOTSUPPORT       (SDR_BASE + 0x00000009)
#define SDR_ALGMODNOTSUPPORT    (SDR_BASE + 0x0000000A)
#define SDR_PKOPERR            (SDR_BASE + 0x0000000B)
#define SDR_SKOPERR            (SDR_BASE + 0x0000000C)
#define SDR_SIGNERR            (SDR_BASE + 0x0000000D)
#define SDR_VERIFYERR          (SDR_BASE + 0x0000000E)
#define SDR_SYMOPERR           (SDR_BASE + 0x0000000F)
#define SDR_STEPERR           (SDR_BASE + 0x00000010)
#define SDR_FILESIZEERR        (SDR_BASE + 0x00000011)
#define SDR_FILENOEXIST        (SDR_BASE + 0x00000012)
#define SDR_FILEOFSERR         (SDR_BASE + 0x00000013)
#define SDR_KEYTYPEERR         (SDR_BASE + 0x00000014)
#define SDR_KEYERR             (SDR_BASE + 0x00000015)
#define SDR_ENCDATAERR         (SDR_BASE + 0x00000016)
#define SDR_RANDERR            (SDR_BASE + 0x00000017)
#define SDR_PRKRERR            (SDR_BASE + 0x00000018)
#define SDR_MACERR             (SDR_BASE + 0x00000019)
#define SDR_FILEEXSITS         (SDR_BASE + 0x0000001A)
#define SDR_FILEWERR           (SDR_BASE + 0x0000001B)
#define SDR_NOBUFFER           (SDR_BASE + 0x0000001C)
#define SDR_INARGERR           (SDR_BASE + 0x0000001D)
#define SDR_OUTARGERR          (SDR_BASE + 0x0000001E)

int SDF_OpenDevice(void **phDeviceHandle);
int SDF_CloseDevice(void *hDeviceHandle);
int SDF_GetDeviceInfo(void *hSessionHandle, DEVICEINFO *pstDeviceInfo);
int SDF_GenerateRandom(void *hSessionHandle, unsigned int uiLength, unsigned char *pucRandom);
int SDF_Encrypt(void *hSessionHandle, void *hKeyHandle, unsigned int uiAlgID,
                unsigned char *pucIV, unsigned char *pucData, unsigned int uiDataLength,
                unsigned char *pucEncData, unsigned int *puiEncDataLength);
int SDF_Decrypt(void *hSessionHandle, void *hKeyHandle, unsigned int uiAlgID,
                unsigned char *pucIV, unsigned char *pucEncData, unsigned int uiEncDataLength,
                unsigned char *pucData, unsigned int *puiDataLength);

#ifdef __cplusplus
}
#endif
#endif // HEADER_SDF_H
